<?php

namespace App\Models;

use App\Models\Traits\HasImageAttribute;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

/**
 * Class CategoryModel
 * @package App\Models
 */
abstract class CategoryModel extends Model
{
    use HasImageAttribute;

    protected $primaryKey = 'catid';
    protected $fillable = [
        'fid', 'name', 'identifier', 'image', 'displayorder',
        'level', 'enable', 'available', 'keywords', 'description',
        'template_index', 'template_list', 'template_detail'
    ];
    protected $appends = ['url'];
    protected $casts = [
        'displayorder' => 'int'
    ];

    public $timestamps = false;

    public static function boot()
    {
        parent::boot(); // TODO: Change the autogenerated stub
        static::addGlobalScope('sort', function (Builder $builder) {
            return $builder->orderBy('level')->orderBy('displayorder')->orderBy('catid');
        });
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
     */
    public function childs()
    {
        return $this->hasMany(static::class, 'fid', 'catid');
    }

    /**
     * @return HasMany
     */
    public function children()
    {
        return $this->childs()->with('children');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function parent()
    {
        return $this->belongsTo(static::class, 'fid', 'catid');
    }

    /**
     * @return HasMany
     */
    public function siblings()
    {
        return $this->hasMany(static::class, 'fid', 'fid');
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeEnable(Builder $query)
    {
        return $query->where('enable', 1);
    }

    /**
     * @return bool
     * @throws \Exception
     */
    public static function updateCache()
    {
        return cache()->forever(static::cacheName(), static::fetchAll());
    }

    /**
     * @return \Illuminate\Database\Eloquent\Collection|static[]
     */
    public static function allFromCache()
    {
        $data = cache()->get(static::cacheName(), null);
        if (is_null($data)) {
            static::updateCache();
            return static::allFromCache();
        }
        return $data;
    }

    /**
     * @return Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public static function fetchAll()
    {
        return static::with('children')->where('fid', 0)->get();
    }

    abstract static public function cacheName();

    abstract public function getUrlAttribute();
}
